package org.bigtree.example.common.utils;

import org.bigtree.example.common.exception.BusinessException;
import org.bigtree.example.common.webapi.IResponseCode;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiPredicate;
import java.util.function.Predicate;

/**
 * 预置检查工具类
 *
 * @author bigTree
 * @since 2025/4/24
 */
public final class PredicateUtils {
    private PredicateUtils() {}

    public static <U> void equalElseThrow(U p1, U p2, IResponseCode responseCode) {
        orElseThrow(Objects.equals(p1, p2), responseCode);
    }

    public static void nullElseThrow(Object obj, IResponseCode responseCode) {
        orElseThrow(obj, Objects::isNull, responseCode);
    }

    public static void emptyElseThrow(String text, IResponseCode responseCode) {
        orElseThrow(!StringUtils.hasLength(text), responseCode);
    }

    public static void emptyElseThrow(Object[] array, IResponseCode responseCode) {
        orElseThrow(array, ObjectUtils::isEmpty, responseCode);
    }

    public static void emptyElseThrow(Collection<?> collection, IResponseCode responseCode) {
        orElseThrow(collection, CollectionUtils::isEmpty, responseCode);
    }

    public static void emptyElseThrow(Map<?, ?> map, IResponseCode responseCode) {
        orElseThrow(map, CollectionUtils::isEmpty, responseCode);
    }

    public static void notNullElseThrow(Object obj, IResponseCode responseCode) {
        orElseThrow(obj, Objects::nonNull, responseCode);
    }

    public static void notEmptyElseThrow(String text, IResponseCode responseCode) {
        orElseThrow(text, StringUtils::hasText, responseCode);
    }

    public static void notEmptyElseThrow(Object[] array, IResponseCode responseCode) {
        orElseThrow(array, arr -> !ObjectUtils.isEmpty(arr), responseCode);
    }

    public static void notEmptyElseThrow(Collection<?> collection, IResponseCode responseCode) {
        orElseThrow(collection, coll -> !CollectionUtils.isEmpty(coll), responseCode);
    }

    public static void notEmptyElseThrow(Map<?, ?> map, IResponseCode responseCode) {
        orElseThrow(map, mp -> !CollectionUtils.isEmpty(mp), responseCode);
    }

    public static <T, U> void orElseThrow(T p1, U p2, BiPredicate<T, U> predicate, IResponseCode responseCode) {
        orElseThrow(predicate.test(p1, p2), responseCode);
    }

    public static <T> void orElseThrow(T param, Predicate<T> predicate, IResponseCode responseCode) {
        orElseThrow(predicate.test(param), responseCode);
    }

    public static void orElseThrow(boolean expr, IResponseCode responseCode){
        if (!expr) {
            throw new BusinessException(responseCode);
        }
    }

    public static <E extends RuntimeException> void orElseThrow(boolean expr, E ex) {
        if (!expr) {
            throw ex;
        }
    }
}
